package org.example.gui;

import javafx.scene.Scene;
import javafx.scene.control.ScrollPane;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.Text;
import javafx.stage.Stage;
import org.example.core.FATManager;

import java.util.HashMap;
import java.util.Map;

/**
 * FAT状态图形化显示窗口
 */
public class FATStatusWindow {
    private final FATManager fatManager;
    private final int blocksPerRow = 16; // 每行显示16个块

    // 颜色定义
    private static final Color FREE_COLOR = Color.WHITE;
    private static final Color ALLOCATED_COLOR = Color.YELLOW;
    private static final Color BAD_BLOCK_COLOR = Color.RED;
    private static final Color SYSTEM_BLOCK_COLOR = Color.LIGHTBLUE;
    private static final Color EOF_COLOR = Color.ORANGE;

    public FATStatusWindow(FATManager fatManager) {
        this.fatManager = fatManager;
    }

    public void show() {
        Stage stage = new Stage();
        stage.setTitle("FAT表状态 - 图形化视图");

        // 创建主容器
        VBox mainContainer = new VBox(10);
        mainContainer.setStyle("-fx-padding: 10; -fx-background-color: #f0f0f0;");

        // 创建标题和说明
        Text title = new Text("文件分配表 (FAT) 状态");
        title.setStyle("-fx-font-size: 16px; -fx-font-weight: bold;");

        Text description = new Text("颜色说明: 白色=空闲, 黄色=已分配, 蓝色=系统块, 橙色=文件结束, 红色=坏块");
        description.setStyle("-fx-font-size: 12px;");

        // 创建图例
        GridPane legend = createLegend();

        // 创建FAT块显示网格
        GridPane fatGrid = createFATGrid();

        // 添加到主容器
        mainContainer.getChildren().addAll(title, description, legend, fatGrid);

        // 创建滚动面板
        ScrollPane scrollPane = new ScrollPane(mainContainer);
        scrollPane.setFitToWidth(true);

        Scene scene = new Scene(scrollPane, 800, 600);
        stage.setScene(scene);
        stage.show();
    }

    /**
     * 创建颜色图例
     */
    private GridPane createLegend() {
        GridPane legend = new GridPane();
        legend.setHgap(10);
        legend.setVgap(5);
        legend.setStyle("-fx-padding: 10; -fx-background-color: #e0e0e0; -fx-background-radius: 5;");

        // 定义图例项
        Map<Color, String> legendItems = new HashMap<>();
        legendItems.put(FREE_COLOR, "空闲块");
        legendItems.put(ALLOCATED_COLOR, "已分配块");
        legendItems.put(SYSTEM_BLOCK_COLOR, "系统块");
        legendItems.put(EOF_COLOR, "文件结束块");
        legendItems.put(BAD_BLOCK_COLOR, "坏块");

        // 添加图例项
        int row = 0;
        for (Map.Entry<Color, String> entry : legendItems.entrySet()) {
            // 创建颜色方块
            Rectangle colorBox = new Rectangle(20, 20);
            colorBox.setFill(entry.getKey());
            colorBox.setStroke(Color.BLACK);

            // 创建标签
            Text label = new Text(entry.getValue());

            // 添加到网格
            legend.add(colorBox, 0, row);
            legend.add(label, 1, row);

            row++;
        }

        return legend;
    }

    /**
     * 创建FAT块显示网格
     */
    private GridPane createFATGrid() {
        GridPane grid = new GridPane();
        grid.setHgap(5);
        grid.setVgap(5);
        grid.setStyle("-fx-padding: 10;");

        // 获取FAT表数据
        byte[] fatTable = getFATTableData();

        // 计算需要的行数
        int rows = (int) Math.ceil((double) fatTable.length / blocksPerRow);

        // 添加列标题
        for (int col = 0; col < blocksPerRow; col++) {
            Text header = new Text(String.format("%02X", col));
            header.setStyle("-fx-font-weight: bold;");
            grid.add(header, col + 1, 0);
        }

        // 添加行标题和块
        for (int row = 0; row < rows; row++) {
            // 添加行标题
            Text rowHeader = new Text(String.format("%02X", row * blocksPerRow));
            rowHeader.setStyle("-fx-font-weight: bold;");
            grid.add(rowHeader, 0, row + 1);

            // 添加该行的块
            for (int col = 0; col < blocksPerRow; col++) {
                int blockIndex = row * blocksPerRow + col;
                if (blockIndex < fatTable.length) {
                    grid.add(createBlockVisualization(blockIndex, fatTable[blockIndex]), col + 1, row + 1);
                }
            }
        }

        return grid;
    }

    /**
     * 创建单个块的视觉表示
     */
    private VBox createBlockVisualization(int blockIndex, byte fatValue) {
        VBox block = new VBox(2);
        block.setStyle("-fx-alignment: center; -fx-padding: 5;");

        // 创建颜色方块
        Rectangle colorRect = new Rectangle(40, 40);
        colorRect.setStroke(Color.BLACK);

        // 根据FAT值设置颜色
        int unsignedValue = fatValue & 0xFF;
        String statusText;

        if (unsignedValue == FATManager.FREE_BLOCK) {
            colorRect.setFill(FREE_COLOR);
            statusText = "FREE";
        } else if (unsignedValue == FATManager.BAD_BLOCK) {
            colorRect.setFill(BAD_BLOCK_COLOR);
            statusText = "BAD";
        } else if (unsignedValue == FATManager.END_OF_FILE) {
            colorRect.setFill(EOF_COLOR);
            statusText = "EOF";
        } else if (blockIndex < 2) { // 系统块
            colorRect.setFill(SYSTEM_BLOCK_COLOR);
            statusText = "SYS";
        } else {
            colorRect.setFill(ALLOCATED_COLOR);
            statusText = String.format("%02X", unsignedValue);
        }

        // 创建块号文本
        Text blockText = new Text(String.format("%03d", blockIndex));
        blockText.setStyle("-fx-font-size: 10px;");

        // 创建状态文本
        Text status = new Text(statusText);
        status.setStyle("-fx-font-size: 10px;");

        // 添加到块容器
        block.getChildren().addAll(blockText, colorRect, status);

        return block;
    }

    /**
     * 获取FAT表数据
     */
    private byte[] getFATTableData() {
        try {
            return fatManager.getFATTable();
        } catch (Exception e) {
            // 备用方案：创建一个默认的FAT表
            byte[] fatTable = new byte[128];
            fatTable[0] = FATManager.END_OF_FILE;
            fatTable[1] = FATManager.END_OF_FILE;
            fatTable[23] = FATManager.BAD_BLOCK;
            fatTable[49] = FATManager.BAD_BLOCK;
            return fatTable;
        }
    }
}